#include<iostream>
#include<unistd.h>
#include<string>
#include<string.h>
#include<sys/types.h>
#include <sys/socket.h>      // sockaddr 基础定义
#include <netinet/in.h>      // sockaddr_in, IPPROTO_TCP, INADDR_ANY等
#include <arpa/inet.h>       // inet_pton, inet_ntop, inet_addr等转换函数
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
// #define CHECK_RET(exp) if(!(exp)){\
//     return false;\      
// }

#define CHECK_RET(exp) \
    do { \
        if (!(exp)) { \
            fprintf(stderr, "Check failed: %s at %s:%d\n", #exp, __FILE__, __LINE__); \
            return false; \
        } \
    } while(0)
//因为宏定义不能直接换行，这里\的作用就是欺骗预处理器，让它以为多行内容是一行内容

class TcpSocket{
    public:
    TcpSocket():_fd(-1) {}
    TcpSocket(int fd):_fd(fd) {}
    ~TcpSocket(){
        Close();
    }
    bool Close(){
        close(_fd);
        return true;
    }
    bool Socket(){
        _fd=socket(AF_INET,SOCK_STREAM,0);
        if(_fd==-1){
            std::cerr<<"socket error\n";
            return false;
        }
        return true;
    }
    bool Bind(u_int16_t port,std::string ip="0.0.0.0"){
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        
        int n=bind(_fd,(sockaddr*)(&addr),sizeof(addr));
        if(n==-1){
            std::cerr<<"bind error\n";
            return false;
        }
        return true;
    }
    bool Recv(std::string* buffer){
        buffer->clear();
        char tmp[1024]={0};
        ssize_t read_size=recv(_fd,tmp,sizeof(tmp)-1,0);
        if(read_size==-1){
            std::cerr<<"recvfrom error\n";
            return false;
        }
        buffer->assign(tmp,read_size);
        return true;
    }
    bool Send(std::string buffer){
        ssize_t send_size=send(_fd,buffer.data(),buffer.size(),0);
        if(send_size==-1){
            std::cerr<<"sendto error\n";
            return false;
        }
        return true;
    }
    //connect作用就是客户端发起三次握手
    bool Connect(std::string ip,u_int16_t port){
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=inet_addr(ip.c_str());
        addr.sin_port=htons(port);
        int n=connect(_fd,(sockaddr*)&addr,sizeof(addr));
        if(n==-1){
            std::cerr<<"connect error\n";
            return false;
        }
        return true;
    }
    //服务端处于监听状态（监听一个文件描述符）
    bool Listen(){
        int n=listen(_fd,5);
        if(n==-1){
            std::cerr<<"listen error\n";
            return false;
        }
        return true;
    }
    //从已完成连接队列中取出连接
    bool Accept(TcpSocket* peer,std::string* ip=nullptr,u_int16_t* port=nullptr) const{
        struct sockaddr_in addr;
        memset(&addr,0,sizeof(addr));
        socklen_t len=sizeof(addr);
        int newfd=accept(_fd,(sockaddr*)&addr,&len);
        if(newfd==-1){
            std::cerr<<"accept error\n";
            return false;
        }
        peer->_fd=newfd;
        if(ip!=nullptr){
            *ip=inet_ntoa(addr.sin_addr);
        }
        if(port!=nullptr){
            *port=ntohs(addr.sin_port);
        }
        return true;
    }
    int Getfd(){
        return _fd;
    }
    private:
    int _fd;
};